//============================================================================
// Copyright (C) 2010 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

enum EMenuStateType
{
	eMenuStateNone					= 0, // uninitialized
	eMenuStateInitMain				= 1, // initialize main menu
	eMenuStateMain					= 2, // run main menue
	eMenuStateInitChooseDifficulty	= 3, // show dlg to choose difficulty level game
	eMenuStateChooseDifficulty		= 4, 
	eMenuStateInitHighScores		= 5, 
	eMenuStateHighScores			= 6, 
	eMenuStateInitOptions			= 7, 
	eMenuStateOptions				= 9, 
	eMenuStateInitVideo				= 10, 
	eMenuStateVideo					= 11, 
	eMenuStateInitAudio				= 12, 
	eMenuStateAudio					= 13, 
	eMenuStateInitTutorial			= 14, 
	eMenuStateTutorial				= 15, 
	eMenuStateInitGameOver			= 16, 
	eMenuStateGameOver				= 17, 
	eMenuStateInitGameOverHighScore	= 18, 
	eMenuStateGameOverHighScore		= 19, 
	eMenuStateInitAddHighScore		= 20, 
	eMenuStateAddHighScore			= 21, 
	eMenuStateInitHighScoreLevel	= 22, 
	eMenuStateHighScoreLevel		= 23, 

	eMenuStateInitGame				= 24,  // start game
//	eMenuStateInitMultiPlayer	= 16, 
//	eMenuStateMultiPlayer		= 17, 
//	eMenuStateInitControls	= 16, 
//	eMenuStateControls		= 17, 

	eMaxMenuStateType, // must be last
};

enum EGuiElements 
{
	EGUI_START_INTEFACE_ID			= 100,	// ids of gui controls will be this or higher
	// main dlg
	EGUI_MAIN_LOGO					= 101,	// logo .. if clicked on go to website
	EGUI_MAIN_PLAY_BUT				= 102,	// play button
	EGUI_MAIN_HIGHSCORE_BUT			= 103,	// high score button
	EGUI_MAIN_OPTIONS_BUT			= 104,	// options button
	EGUI_MAIN_TUTORIAL_BUT			= 105,	// tutorial
	EGUI_MAIN_EXIT_BUT				= 106,	// exit button
	// single player hard/medium/easy
	EGUI_PLAY_HARD_BUT				= 110,
	EGUI_PLAY_HARD_INFO_BUT			= 111,
	EGUI_PLAY_MEDIUM_BUT			= 112,		
	EGUI_PLAY_MEDIUM_INFO_BUT		= 113,
	EGUI_PLAY_EASY_BUT				= 114,
	EGUI_PLAY_EASY_INFO_BUT			= 115,
	EGUI_PLAY_BACK_BUT				= 116,
	EGUI_PLAY_START_GAME_BUT		= 117,
	EGUI_PLAY_TUTORIAL				= 118,
	// pick high score hard/medium/easy dlg
	EGUI_PICK_HIGHSCORE_HARD_BUT	= 120,
	EGUI_PICK_HIGHSCORE_MEDIUM_BUT	= 121,
	EGUI_PICK_HIGHSCORE_EASY_BUT	= 122,
	EGUI_PICK_HIGHSCORE_BACK_BUT	= 123,
	// show high score hard/medium/easy dlg back button
	EGUI_SHOW_HIGHSCORE_BACK_BUT	= 130,
	// show users play info dlg for the given level
	EGUI_LEVEL_INFO_DESCRIPTION_TEXT	= 140,
	EGUI_LEVEL_INFO_ATTEMPTS_TEXT	= 141,
	EGUI_LEVEL_INFO_WINS_TEXT		= 142,
	EGUI_LEVEL_INFO_LOSES_TEXT		= 143,
	EGUI_LEVEL_INFO_PLAYTIME_TEXT	= 144,
	EGUI_LEVEL_INFO_BESTTIME_TEXT	= 145,
	EGUI_LEVEL_INFO_BACK_BUT		= 145,
	// options main dlg
	EGUI_OPTIONS_VIDEO			= 150,
	EGUI_OPTIONS_AUDIO			= 151,
	EGUI_OPTIONS_CONTROLS		= 152,
	EGUI_OPTIONS_BACK			= 153,
	EGUI_OPTIONS_SHOW_TUTORIAL	= 154,
	// video settings dlg
	EGUI_VIDEO_VIDEOMODES		= 160,
	EGUI_VIDEO_ANTIALIAS		= 161,
	EGUI_VIDEO_SHADOWS			= 162,
	EGUI_VIDEO_SAVE				= 163,
	EGUI_VIDEO_CANCEL			= 164,
	// audio settings dlg
	EGUI_AUDIO_ENABLED			= 170,
	EGUI_AUDIO_SOUND_VOLUME		= 171,
	EGUI_AUDIO_MUSIC_VOLUME		= 172,
	EGUI_AUDIO_SAVE				= 173,
	EGUI_AUDIO_CANCEL			= 174,
	// tutorial
	EGUI_TUTORIAL_DONE			= 180,
	// game over
	EGUI_GAME_OVER_DONE			= 190,
	// game over with high score
	EGUI_GAME_OVER_HIGH_SCORE_CANCEL	= 200,
	EGUI_GAME_OVER_HIGH_SCORE_ADD_SCORE	= 201,
	// enter name for high score
	EGUI_ADD_SCORE_DONE					= 210,
	EGUI_ADD_SCORE_OK					= 211,
	EGUI_ADD_SCORE_EDIT_BOX				= 212,
	// which high score to view
	EGUI_PICK_HIGHSCORE_EASY			= 220,
	EGUI_PICK_HIGHSCORE_MEDIUM			= 221,
	EGUI_PICK_HIGHSCORE_HARD			= 222,

	// for keyboard
	EGUI_KEY_BASE_ID					= 5000,

	EGUI_MAX_ID
};

enum EGuiFontSize
{
	eGuiFontSmall	= 0,
	eGuiFontMedium	= 1,
	eGuiFontLarge	= 2,
	eGuiFontFixed	= 3,
	eMaxGuiFontSize, // must be last
};

enum EGuiAlignType 
{
	eGuiAlignLeft	= 0,
	eGuiAlignCenter = 1,
	eGuiAlignRight	= 2,
};

enum EGuiSkinType 
{
	eGuiSkinTypeNone = 0,
	eGuiSkinTypeMenu = 1,
	eGuiSkinTypeGame = 2,
	eGuiSkinTypeNeedSlider = 3,
	eMaxGuiSkinType, // must be last
};
enum EGuiImageType 
{
	eGuiImageMouseCursor,
	eGuiImageBlack,
	eGuiImageTextBoxCorner,
	eGuiImageTextBoxLeftEdge,
	eGuiImageTextBoxTopEdge,
	eGuiImageButton80x32,
	eGuiImageButton100x32,
	eGuiImageButton128x32,
	eMaxGuiImageType,
};

class TutorialTextInfo
{
public:
	irr::core::stringc	m_strText;
	U32					m_u32DeleteTime;
};

enum EMenuSound
{
	eMenuSoundClick = 0,

	eMaxMenuSounds, // must be last
};
class DtwStateMenu : public GameStateBase
{
public:
	//=== vars ===//
	DtwGameMgr *					m_poGameMgr;				// game manager
	//=== menu vars ===//
	EMenuStateType					m_eCurMenuState;			// current state
	EMenuStateType					m_eTargetMenuState;			// next state if any
	AudioSource	*					m_apoMenuSounds[ eMaxMenuSounds ];
	U32								m_u32DoubleClickTimer;		// timer for button doubleclick
	irr::gui::IGUIEditBox *			m_poAddHighScoreNameEditBox;// edit box for user to enter his name for high score

	//=== selection vars ===//	
	int				m_iCampaignIdx;			// index of selected campain 
	int				m_iSelectedLevel;		// selected level
	int				m_iDifficultyLevel;		// level of difficulty of game the user chose

	// Level info
	irr::core::array< SaveLevelStats *> m_apoLevelStats;

	//=== display vars ===//
	int				m_iScnSizeX;			// width of display
	int				m_iScnSizeY;			// height of display
	float			m_f32ScaleWidth;		// scale of width of display
	float			m_f32ScaleHeight;		// scale of height of display
	EGuiFontSize	m_eDefaultFontSize;		// default font size for size of display


	//=== graphics vars ===//
	irr::gui::IGUISkin *			m_poGuiSkin;
	TutorialTextInfo				m_oTutorialTextInfo;
	U32								m_u32Timer;

	irr::gui::IGUIFont *			m_apoFonts[ eMaxGuiFontSize ];
	irr::video::ITexture *			m_apoGuiImages[ eMaxGuiImageType ];

	//=== keyboard vars ===//
	U8								m_au8QwertyKeys[28];

	//=== constructor ===//
	DtwStateMenu();
	//=== destructor ===//
	~DtwStateMenu();

	//=== state overrides ===//
	//! startup
	virtual RCODE	GameStateStartup( VxIrrBase * poIrrBase );
	//! shutdown
	virtual void	GameStateShutdown( void );
	//! update current game state
	virtual RCODE	GameStateUpdate( U32 u32FrameTimeMs );
	//! called when application is resuming from sleep.. app must reload textures etc
	virtual RCODE	GameStateAppResume( U32 u32FrameTimeMs );
	//! load textures for menu
	//! bReloadFromResume = true if reloading after application resume
	virtual RCODE	LoadMenuResources( BOOL bReloadFromResume );
	//! draw scene
	virtual void	Draw( void );
	//! render a frame
	virtual void	RenderMenuFrame( void );

	//! handle gui events
	virtual bool	OnGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );

	//=== input handlers ===//

	//=== properties ===//
	//! get gui image
	irr::video::ITexture *		GetImage( EGuiImageType eGuiImage )		{ return m_apoGuiImages[ eGuiImage ]; }
	//! get gui font
	irr::gui::IGUIFont *		GetFont( EGuiFontSize eGuiFont )		{ return m_apoFonts[ eGuiFont ]; }
	//! set tutorial text and how log to show it
	void	SetTutorialText( irr::core::stringc& strText, U32 u32TTL )	{ m_oTutorialTextInfo.m_strText = strText; m_oTutorialTextInfo.m_u32DeleteTime = m_u32Timer + u32TTL; } 

	//! get rectagle in centered in center of screen
	irr::core::rect<irr::s32>	GetCenteredRect( int iPosX, int iPosY, int iWidth, int iHeight);
	//! make irrlicht rect from screen positions
	irr::core::rect<irr::s32>	GetRect( int iPosX, int iPosY, int iWidth, int iHeight);

	//=== methods ===//
	//! play button click sound
	void	PlayButtonClick( void );

	//! change gui skin
	void	ChangeSkin( EGuiSkinType eSkinType );
	//! reset all elements
	void	ClearAll( void ); 
	//! convert time to string to display
	void	ConvertTimeToString( U32 u32TimeMs, char * pRetBuf );
	//! fade screen to black
	void	FadeScreen( F32 f32FadeAmount );
	//! if tutorial text has been set then draw it
	void	DrawTutorialText( void );

	//! render text
	void	RenderText(	const char * pText,		
						int iPosX, 
						int iPosY, 
						EGuiAlignType eAlignType, 
						EGuiFontSize eFontSize = eGuiFontSmall, 
						const irr::video::SColor& oColor = irr::video::SColor(255, 255, 255, 255) );
	//! draw image centered around a position
	void	DrawImage( EGuiImageType eImageType, int iPosX, int iPosY, int iWidth, int iHeight, const irr::video::SColor& oColor = irr::video::SColor(255, 255, 255, 255) ); 
	//! draw a rounded text box
	void	DrawTextBox(int iPosX, int iPosY, int iWidth, int iHeight, const irr::video::SColor& oColor = irr::video::SColor(255, 255, 255, 255) ); 
private:
	//=== private methods ===//

	//=== build menu funtions in DtwStateMenuInit.cpp ===//
	//! clear any buttons etc from previous menu
	void	ClearPreviousMenu( void );

	//! build main menu
	RCODE	InitMenuMain( void );
	//! build menu to choose game play difficulty
	RCODE	InitMenuChooseDifficulty( void );
	//! build menu showing high scores
	RCODE	InitMenuHighScores( void );
	//! build menu showing config options
	RCODE	InitMenuOptions( void );
	//! build menu video settings
	RCODE	InitMenuVideo( void );
	//! build menu showing audio settings
	RCODE	InitMenuAudio( void );
	//! build menu to select tutorial
	RCODE	InitMenuTutorial( void );
	//! build menu to show game over but not high score
	RCODE	InitGameOver( void );
	//! build menu to show game over with high score
	RCODE	InitGameOverHighScore( void );
	//! build menu to allow user to add high score
	RCODE	InitAddHighScore( void );
	//! build menue to allow user to pick which level of high scores to view
	RCODE	InitHighScoreLevel( void );


	//=== event handlers in DtwStateMenuEvents.cpp ===//
	//! handle irrlicht button event
	bool	OnGuiButtonClicked( irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for main menu
	bool	MenuMainGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for choosing game difficulty level
	bool	MenuChooseDifficultyGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for viewing high scores
	bool	MenuHighScoresGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for options menu
	bool	MenuOptionsGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for video options
	bool	MenuVideoGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for options menu
	bool	MenuAudioGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for tutorial
	bool	MenuTutorialGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for game over
	bool	MenuGameOverGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events for game over with high score
	bool	MenuGameOverHighScoreGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events to allow user to add high score
	bool	MenuAddHighScoreGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! handle gui events to allow user to pick which level of high scores to view
	bool	MenuHighScoreLevelGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );

	//! display high scores
	void	DisplayHighScores( int iCenterX, int iCurYPos, irr::core::array<HighScoreEntry>& aoScoreEntries );


};
